/* eslint-disable no-void */
// import axios from "axios";
import qs from "qs";
import { merge } from "@/utils";

import store from "@/store";
import router from "@/router";
const axios = require("axios").default;
const CancelToken = axios.CancelToken;
const cancelArray: any = [];
interface AxiosRequestConfig{
    url: any;
    proxy?: any;
    method: any;
    data?: any;
    params?: any;
    loader?: any;
    complete?: any;
    responseType?: any;
    cancelToken?: any;
    before?: any;
    headers?: any;
}
export default async(options: AxiosRequestConfig) => {
    let opt: AxiosRequestConfig = {
        url: "",
        proxy: "",
        method: "GET",
        data: {},
        params: false,
        loader: true,
        complete: null,
        responseType: "json",
        cancelToken: null,
        before: null,
        headers: {}
    };
    opt = merge(true, opt, options);
    opt.method = opt.method.toUpperCase();
    if (opt.method === "GET" || opt.method === "DELETE") {
        // const response = await axios.get(opt.url,{params:opt.data});
        const response = await axios({
            method: opt.method,
            url: opt.url,
            params: opt.data,
            proxy: {
                loader: opt.loader
            },
            cancelToken: new CancelToken(function(c: any) {
                // An executor function receives a cancel function as a parameter
                const cancelFn = function(cn: any, _opt: any, _store: any) {
                    return (msg: any) => {
                        if (_opt.loader) {
                            _store.dispatch("ajaxRequestEnd");
                        }
                        cn(msg);
                    };
                };
                const _cancelToken = cancelFn(c, opt, store);
                opt.cancelToken && opt.cancelToken(_cancelToken);
                cancelArray.push(_cancelToken);
            }),
            responseType: opt.responseType,
            headers: {
                ...opt.headers
            }
        });
        return response;
    }
    if (opt.method === "POST" || opt.method === "PUT") {
        // const response = await axios.post(opt.url,opt.data);
        const headersContentType =
            opt.headers["Content-Type"] || "application/x-www-form-urlencoded";
        const stringify =
            !opt.headers["Content-Type"] ||
            opt.headers["Content-Type"] === "application/x-www-form-urlencoded";
        const response = await axios({
            method: opt.method,
            url: opt.url,
            proxy: {
                loader: opt.loader
            },
            params: opt.params ? opt.data : {},
            data: opt.params ? {} : stringify ? qs.stringify(opt.data) : opt.data,
            // data: opt.data,
            cancelToken: new CancelToken(function(c: any) {
                // An executor function receives a cancel function as a parameter
                const cancelFn = function(cn: any, _opt: any, _store: any) {
                    return (msg: any) => {
                        if (_opt.loader) {
                            _store.dispatch("ajaxRequestEnd");
                        }
                        cn(msg);
                    };
                };
                const _cancelToken = cancelFn(c, opt, store);
                opt.cancelToken && opt.cancelToken(_cancelToken);
                cancelArray.push(_cancelToken);
            }),
            responseType: opt.responseType,
            headers: {
                "Content-Type": headersContentType,
                ...opt.headers
            }
        });
        return response;
    }
};

// 添加一个请求拦截器
axios.interceptors.request.use(
    function(config: any) {
        // 在请求发送之前做一些事
        if (config.proxy.loader) {
            store.dispatch("ajaxRequestStart");
        }
        return config;
    },
    function(error: any) {
        return Promise.resolve(error);
    }
);

// 添加一个返回拦截器
axios.interceptors.response.use(
    async function(response: any) {
        // 对返回的数据进行一些处理
        if (response.config.proxy.loader) {
            store.dispatch("ajaxRequestEnd");
        }

        return response;
    },
    async function(error: any) {
        // 对返回的错误进行一些处理
        console.dir(error);
        if (axios.isCancel(error)) {
            console.log("请求取消:" + error.message);

            return Promise.resolve({
                cancel: axios.isCancel(error),
                ...error,
                msg: error.message
            });
        }
        if (error.config.proxy.loader) {
            store.dispatch("ajaxRequestEnd");
        }
        if (
            error.response === void 0 ||
            (error.message.indexOf("Network") !== -1 &&
                error.message.indexOf("Error") !== -1)
        ) {
            console.log("服务器地址不存在！");

            return Promise.resolve(error);
        }
        const _status = error.response.status;
        switch (_status) {
        case 400:
            error.message = "错误的请求";
            break;
        case 401:
            error.message = "登录过期";
            break;
        case 403:
            error.message = "拒绝访问";
            break;
        case 404:
            error.message = `错误的地址: ${error.response.config.url}`;
            break;
        case 408:
            error.message = "请求超时";
            break;
        case 500:
        case 501:
        case 502:
        case 503:
        case 504:
        case 505:
            error.message = "服务器错误";
            break;
        default:
            error.message = "未知错误";
            break;
        }
        error.msg = error.message;
        if (_status === 401) {
            const user = store.getters.getUser;
            // 判断登录是否过期,如已过期则删除登录状态
            //
            const isExpiredJwtToken =
                error.response.data.error &&
                error.response.data.error.name === "ExpiredJwtToken";
            if (!isExpiredJwtToken) {
                console.dir(error);
                if (!user.isSignIn) {
                    return Promise.resolve(error);
                }
                await store.dispatch("logout");
                cancelArray.map((cancel: any) => {
                    cancel("登录过期");
                });
                router.replace({
                    path: "/auth/login",
                    query: {
                        redirect: router.app.$route.fullPath
                    }
                });
                const errorMsg = `“${(user.userInfo && user.userInfo.username) ||
                    "未知账号"}”登录过期!`;
                console.log(errorMsg);
                error.msg = errorMsg;
                error.message = errorMsg;
                return Promise.resolve(error);
            } else {
                if (!user.isSignIn) {
                    return Promise.resolve(error);
                }
                // const diff = store.refreshAxiosTime.length !== 2 ? true : store.refreshAxiosTime[1] - store.refreshAxiosTime[0] <= 2000;
                // if (diff) {
                await store.dispatch("refreshToken");
                //     store.refreshAxiosTime[0] = +new Date();
                // }
                // store.refreshAxiosTime[1] = +new Date();
                error.response.config.headers.Authorization =
                    "Bearer " + user.auth.token;
                cancelArray.shift();
                return axios(error.response.config);
            }
        }
        if (_status !== 400) {
            console.log(error.message);
        }
        return Promise.resolve(error);
    }
);
